//
//  Plugin.m
//  SimpleSearch
//
//  Created by Ryan on Tue Nov 11 2003.
//
//  ****************
//  Short Disclaimer (please read!):
//
//  Why open source?  This project was briefly popular several years ago and has since lost interest (on both
//  my part and the public's part).  Rather than letting it moulder for eternity, I decided to open source it 
//  in case anyone else is interested in renovating it and bringing it up to date.
//
//  My main concern with open sourcing it is that this program is one of the first Cocoa programs I wrote and
//  as such, it is in no way representative of my current coding style!  Many things are done incorrectly in 
//  this code base but I have not taken the time to revise them for the open source release. Hence, if you work
//  for a company looking to hire me, don't look too critically at this old code!
//
//  This code was originally written in 2002 to 2003 and hence was created before technologies such as 
//  Cocoa Bindings and properties (Obj-C 2.0) existed.  Much of the code could be ripped out and replaced 
//  with the newer way of doing things.
//
//  The GUI is also fairly out of date and in need of some serious updating.
//  
//  Have fun!
//  April, 2008.
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.


#import "Plugin.h"


@implementation Plugin


- (id)initWithPath: (NSString*)path {
	if (self = [super init]) {
		if (! [self readPluginAtPath: path]) {
			return nil;
		}
	}
	return self;
}

/*
// Used if you want to create a special plugin such as a URL or RunProgram type.
- (id)initWithSpecialType: (PluginType)t {
	if (self = [super init]) {
			type = t;
		
		NSNumber * num;
		num = [NSNumber numberWithInt: 1];
		
		// Basically, we're creating the plugin dictionary by hand instead of bothering with an XML file.
		NSDictionary * d = [NSDictionary dictionaryWithObjectsAndKeys:
			@"http://www.chimoosoft.com/", @"OptionBaseURL", @"Normal", @"OptionName", nil];
		
		switch (type) {
			case P_URL: 			
				pluginDict = [NSDictionary dictionaryWithObjectsAndKeys: 
					@"URL", @"PluginName", num, @"NumOptions", d, @"Option0", nil];
				[pluginDict retain];
				break;
			case P_RUNPROGRAM:
				pluginDict = [NSDictionary dictionaryWithObjectsAndKeys: 
					@"Run Program", @"PluginName", num, @"NumOptions", d, @"Option0", nil];
				[pluginDict retain];				
				break;
		}

	}
	return self;	
}
*/


- (NSString *)description {
	return [NSString stringWithFormat: @"plugin called: %@", [self name]];
}


- (BOOL)readPluginAtPath: (NSString*)path {
	type = P_NORMAL;		// Assume it's a normal plugin to start with just in case.
	
	NSFileManager * fm = [NSFileManager defaultManager];
	
	if (![fm fileExistsAtPath: path]) { return NO; }
		
	pluginDict = [[NSDictionary dictionaryWithContentsOfFile: path] retain];

	if (pluginDict) {
		if ([[pluginDict objectForKey:@"PluginType"] isEqualToString:@"normal"]) {
			type = P_NORMAL;
		} else if ([[pluginDict objectForKey:@"PluginType"] isEqualToString:@"runprogram"]) {
			type = P_RUNPROGRAM;
		} else if ([[pluginDict objectForKey:@"PluginType"] isEqualToString:@"showurl"]) { 
			type = P_URL;
		}
	}
	
	return (nil != pluginDict);
}


- (NSString *)name { 
	return [pluginDict objectForKey: @"PluginName"]; 
}


- (NSString *)submittedBy {
	return [pluginDict objectForKey: @"SubmittedBy"];
}

- (int)numOptions { 
	return [[pluginDict objectForKey: @"NumOptions"] intValue];
}


// Return the user defined KeyEquivalent or an empty string if none exists.
- (NSString *)keyEquivalent {
	NSDictionary * d;
	d = [pluginDict objectForKey: [NSString stringWithFormat: @"KeyEquivalent", index]];

	if ([d objectForKey: @"Key"] != nil) {
		return [d objectForKey: @"Key"];
	}
	
	else return @"";
}


// Return the keyEquivalentMask for this plugin.  In other words, is it a command,
// command-shift, command-option, etc., etc.
- (unsigned int)keyEquivalentMask {
	NSDictionary * d;
	d = [pluginDict objectForKey: [NSString stringWithFormat: @"KeyEquivalent", index]];
	
	unsigned int mask;
	
	mask = NSCommandKeyMask;  // Must start with this - not optional.

	if ([[d objectForKey:@"Control"] boolValue]) {
		mask = mask | NSControlKeyMask;			 } 
	if ([[d objectForKey:@"Option"] boolValue]) {
		mask = mask | NSAlternateKeyMask;		 }
	if ([[d objectForKey:@"Shift"] boolValue])  {
		mask = mask | NSShiftKeyMask;	         }
	
	return mask;
}


- (NSString *)nameAtIndex:(int)index {
	NSDictionary * d;
	d = [pluginDict objectForKey: [NSString stringWithFormat: @"Option%d", index]];
	
	return [d objectForKey: @"OptionName"];
}


- (NSURL *)URLAtIndex:(int)index {
	NSDictionary * d;
	d = [pluginDict objectForKey: [NSString stringWithFormat: @"Option%d", index]];
	
	return [NSURL URLWithString: [d objectForKey: @"OptionBaseURL"]];
}


// Make sure the index is valid.
- (BOOL)rangeCheck:(int)i {
	return ((i >= 0) && (i < [self numOptions]));
}


- (NSString *)escapeURLString:(NSString *)s {
// Let Core Foundation figure it out!

	return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, 
		(CFStringRef)s, NULL, NULL, kCFStringEncodingWindowsLatin1);
	
	// Note, this *really* doesn't make sense.  I'm not sure why I had to 
	// use kCFStringEncodingWindowsLatin1 instead of the 
	// expected kCFStringEncodingUTF8.  ???
	
}

- (PluginType)pluginType {
	return type;
}


// Pass this the option index and a query, and it will use the appropriate
// base URL to show the site in the user's web browser
- (void)showWebSiteWithOptionIndex: (int)index query: (NSString*)q {
	if (! [self rangeCheck: index]) { return; }
	
	NSMutableString * s;
	NSURL * url;
	NSWorkspace * ws;
		
	
	switch (type) {
		case P_NORMAL:
			
			s = [[NSMutableString alloc] init];
			[s setString: [[self URLAtIndex: index] absoluteString]];
			[s appendString: [self escapeURLString: q]];
			
			// We have to % escape the proper characters such as space, etc..
//			NSString * safe = [self escapeURLString:s];
//			NSLog(@"safe: %@", safe);
			
			url = [NSURL URLWithString: s];
			
			// Show the URL.
			[[NSWorkspace sharedWorkspace] openURL:url];
			
			[s release];
			
			break;
			
		case P_URL:
			url = [NSURL URLWithString: [self escapeURLString: q]];
			[[NSWorkspace sharedWorkspace] openURL:url];
			
			break;
			
		case P_RUNPROGRAM:
			ws = [NSWorkspace sharedWorkspace];
			[ws launchApplication: q];
			
			break;
	}
}


- (void)dealloc {
	[pluginDict release];
	[super dealloc];
}

@end
